package org.jugile.util;

/*

Copyright (C) 2007-2011 Jukka Rahkonen  email: jukka.rahkonen@iki.fi

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Properties;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * "And the king of Sodom went out to meet him after his return from the slaughter of 
 *  Chedorlaomer, and of the kings that were with him, at the valley of Shaveh, 
 *  which is the king's dale. 
 *  And Melchizedek king of Salem brought forth bread and wine: 
 *  and he was the priest of the most high God. And he blessed him, and said, 
 *  Blessed be Abram of the most high God, possessor of heaven and earth:
 *  And blessed be the most high God, which hath delivered thine enemies into thy hand. 
 *  And he gave him tithes of all." (Gen 14:17-20)
 * 
 * ==========
 * 
 * @author jukka.rahkonen@iki.fi
 */
public class Pdf extends Jugile {

	private Document doc;
	private PdfWriter writer;
	private PdfContentByte cb;
	private BaseFont bf;
	private PdfPTable table;
	private PdfPCell cell;
	
	private float fontsize = 12;
	public void fontsize(float v) { fontsize = v; }
	
	private float leading = 1.4f;
	public void leading(float v) { leading = v; }

	private int fontstyle = Font.NORMAL;
	public void fontstyle(String fs) {
		if ("b".equals(fs)) fontstyle = Font.BOLD;
		if ("bi".equals(fs)) fontstyle = Font.BOLDITALIC;
		if ("i".equals(fs)) fontstyle = Font.ITALIC;
		if ("n".equals(fs)) fontstyle = Font.NORMAL;
		if ("".equals(fs)) fontstyle = Font.NORMAL;
		if (fs == null) fontstyle = Font.NORMAL;
		if ("st".equals(fs)) fontstyle = Font.STRIKETHRU;
		if ("u".equals(fs)) fontstyle = Font.UNDERLINE;
	}
	
	public final static Font.FontFamily HELVETICA = Font.FontFamily.HELVETICA;
	public final static Font.FontFamily COURIER = Font.FontFamily.COURIER;
	public final static Font.FontFamily TIMES = Font.FontFamily.TIMES_ROMAN;
	public final static Font.FontFamily DINGBATS = Font.FontFamily.ZAPFDINGBATS;
	private Font.FontFamily fontfamily = Font.FontFamily.HELVETICA;
	public void font(Font.FontFamily ffm) { fontfamily = ffm; }
	
	public void font(Font.FontFamily ffm, float size, String style) {
		fontfamily = ffm;
		fontsize(size);
		fontstyle(style);
	}
	public void font(float size, String style) {
		fontsize(size);
		fontstyle(style);
	}
	public void font(float size) {
		fontsize(size);
	}
	
	public void open(String filename, String pagesize) throws Exception {
		open(filename, pagesize, 72,72,72,72);
	}
	public void open(String filename, String pagesize, float left, float right, float top, float bottom) throws Exception {
		Rectangle psize = PageSize.A4;
		if ("A5".equals(pagesize)) psize = PageSize.A5;
		if ("A3".equals(pagesize)) psize = PageSize.A3;
		doc = new Document(psize);
		doc.setMargins(left, right, top, bottom); // left, right, top, bottom
		writer = PdfWriter.getInstance(doc, new FileOutputStream(filename));
		doc.open();
		bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);			
		cb = writer.getDirectContent();		
	}

	public void setMargins(float left, float right, float top, float bottom) {
		doc.setMargins(left, right, top, bottom);
	}
	
	public void add(Element e) throws Exception { 
		doc.add(e);
	} 
	
	private String[] alignments;
	private int border = 0;
	public void border(int v) { border = v; }
	public void table(float[] widths, float totalWidth, int borderwidth) {
		table = new PdfPTable(widths);
		table.setTotalWidth(totalWidth);
		border = borderwidth;
		alignments = new String[widths.length];
		cellcount = 0;
	}
	public void align(int col, String alignment) { alignments[col] = alignment;	}

	private int cellcount = 0;
	public void cell(int colspan, String txt, String align) {
		Font f = new Font(fontfamily, fontsize, fontstyle);
		PdfPCell c = new PdfPCell(new Phrase(txt,f));
		int col = cellcount % alignments.length;
		String al = alignments[col];
		if (al != null) {
			//print("align: " + col + " " + al);
			if ("right".equals(al)) c.setHorizontalAlignment(Element.ALIGN_RIGHT);
			if ("left".equals(al)) c.setHorizontalAlignment(Element.ALIGN_LEFT);
			if ("center".equals(al)) c.setHorizontalAlignment(Element.ALIGN_CENTER);
		}
		c.setBorder(border);
		if (colspan > 1) {
			c.setColspan(colspan);
			cellcount += colspan;
		} else {
			cellcount++;
		}
		table.addCell(c);
	}
	public void cell(String txt) { cell(0,txt,null); }
	public void cell(int colspan, String txt) { cell(colspan,txt,null); }
	
	public void putTable(float x, float y) throws Exception {
		table.writeSelectedRows(0, -1, x, top(y), cb);
	}
	
	public void text(String txt, float x, float y) throws Exception {
		cb.beginText();
        cb.setFontAndSize(bf, fontsize);
        cb.moveText(x, top(y));
        //X(x,y);
        cb.setLeading(leading * fontsize);
        for (String line : txt.split("\n")) {
            cb.showText(line);
        	cb.newlineText();
        }
        cb.endText();
	}
	
	public void line(float x1, float y1, float x2, float y2) {
		y1 = top(y1);
		y2 = top(y2);
		cb.moveTo(x1, y1);
		cb.lineTo(x2, y2);
		cb.stroke();
	}
	
	public void rect(float x, float y, float w, float h) {
		y = top(y+h);
		cb.rectangle(x, y, w, h);
		cb.stroke();
	}
	
	public void X(float x, float y) throws Exception {
		y = top(y);
		float s = 5;
		cb.moveTo(x, y);
        cb.lineTo(x-s, y-s);
		cb.moveTo(x, y);
        cb.lineTo(x-s, y+s);
		cb.moveTo(x, y);
        cb.lineTo(x+s, y-s);
		cb.moveTo(x, y);
        cb.lineTo(x+s, y+s);        
        cb.stroke();
	}

	public Image imgResource(String name) throws Exception {
		InputStream is = this.getClass().getResourceAsStream(name);
		if (is == null) return null;
	    byte[] input = new byte[1000000]; // max size 1M
	    for (int i = 0; i < input.length; i++) {
	      int b = is.read( );
	      if (b  == -1) break;
	      input[i] = (byte) b;
	    }
		return Image.getInstance(input);
	}

	public Image img(String fname) throws Exception {
		return Image.getInstance(fname);
	}
	public void img(String fname, float x, float y, float width, float height) throws Exception {
		Image img = Image.getInstance(fname);
		img(img, x,y,width,height);
	}
	
	public void img(Image img, float x, float y, float width, float height) throws Exception {
		float iw = img.getWidth();
		float ih = img.getHeight();
		if (height <= 0) {
			// calculate
			height = width * ih/iw;			
		}
		if (width <= 0) {
			// calculate
			width = height * ih/iw;			
		}
		y = top(y+height);
		cb.addImage(img, width, 0, 0, height, x, y);
	}
	
	public void newpage() {
		doc.newPage();
	}
	public void close() {
		doc.close();
	}
	
	public float mm(float mm) {
		return mm * (595.0f / 210.0f);
	}
	public float top(float y) {
		return 842f -y;
	}
	
	

}
